#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include <time.h>
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include "os_api.h"
#include "debug.h"
#include "dev_api.h"
#include "gnss.h"


typedef struct{
    int len;
    char *data;
} gnssMsgParam;

#define _STACK_SIZE	(5*1024)

static void* _task_stack = NULL;

static OSTaskRef _task_ref = NULL;

static OSMsgQRef gnss_msgq_ref = NULL;


#define GNSS_SENTENCE_LENGTH	200

static char gnss_RMC_Sentence[GNSS_SENTENCE_LENGTH] = {0};
static char gnss_GGA_Sentence[GNSS_SENTENCE_LENGTH] = {0};
static char gnss_VTG_Sentence[GNSS_SENTENCE_LENGTH] = {0};
static char gnss_GSA_Sentence[GNSS_SENTENCE_LENGTH] = {0};
static char gnss_GLL_Sentence[GNSS_SENTENCE_LENGTH] = {0};

void gnss_process_nmea_sting(char *data)
{
	int i;
	static int tempLen = 0;
	static char tempSentence[GNSS_SENTENCE_LENGTH]= {0};

	//LOG_PRINTF("gnss_process_nmea_sting : %s\n", data);
	
	for (i = 0; i < strlen(data); i++){
        if (tempLen >= sizeof(tempSentence)) {
            memset(tempSentence, 0x0, GNSS_SENTENCE_LENGTH);
            tempLen = 0;
        }
		if (*(data+i) == 0x0D){
			tempSentence[tempLen++] = *(data+i);
		}else if (*(data+i) == 0x0A){
			tempSentence[tempLen++] = *(data+i);
			LOG_PRINTF("tempSentence : %s", tempSentence);

			if (!strncmp(tempSentence, "$GNGGA", strlen("$GNGGA"))){
				memset(gnss_GGA_Sentence, 0x0, GNSS_SENTENCE_LENGTH);
				memcpy(gnss_GGA_Sentence, tempSentence, strlen(tempSentence));
			}else if (!strncmp(tempSentence, "$GNGSA", strlen("$GNGSA"))){
				memset(gnss_GSA_Sentence, 0x0, GNSS_SENTENCE_LENGTH);
				memcpy(gnss_GSA_Sentence, tempSentence, strlen(tempSentence));
			}else if (!strncmp(tempSentence, "$GPGSV", strlen("$GPGSV"))){

			}else if (!strncmp(tempSentence, "$GNRMC", strlen("$GNRMC"))){
				memset(gnss_RMC_Sentence, 0x0, GNSS_SENTENCE_LENGTH);
				memcpy(gnss_RMC_Sentence, tempSentence, strlen(tempSentence));				
			}else if (!strncmp(tempSentence, "$GPVTG", strlen("$GPVTG"))){
				memset(gnss_VTG_Sentence, 0x0, GNSS_SENTENCE_LENGTH);
				memcpy(gnss_VTG_Sentence, tempSentence, strlen(tempSentence));
			}else if (!strncmp(tempSentence, "$GNGLL", strlen("$GNGLL"))){
				memset(gnss_GLL_Sentence, 0x0, GNSS_SENTENCE_LENGTH);
				memcpy(gnss_GLL_Sentence, tempSentence, strlen(tempSentence));
			}else{
				
			}
	
			memset(tempSentence, 0x0, GNSS_SENTENCE_LENGTH);
			tempLen = 0;
		}else{
			tempSentence[tempLen++] = *(data+i);
		}
	}
}


void gnssDataRecvCallback(GNSS_EVENT_T_E eventid, void *data)
{	
	if (eventid == EVENT_AGNSS_RESULT){
		
		LOG_PRINTF("EVENT_AGNSS_RESULT: %d", (int)data);
		
	}else if (eventid == EVENT_GNSS_DATA || eventid == EVENT_GNSS_NMEA){
		
		OSA_STATUS osa_status;
		gnssMsgParam gnssMsqData = {0};
		
		//LOG_PRINTF("gnssDataRecvCallback: %s", gnssData);

		gnssMsqData.data = (char *)strdup((char *)data);
		gnssMsqData.len = strlen((char *)data);

		osa_status = OSAMsgQSend(gnss_msgq_ref, sizeof(gnssMsgParam), (UINT8 *)&gnssMsqData, OSA_NO_SUSPEND);
		ASSERT(osa_status == OS_SUCCESS);
	}
}


static void _task(void *ptr)
{
	int ret;
	int count = 0;
	OSA_STATUS status;
	gnssMsgParam gnssMsqData = {0};
	
	//ret = hal_GnssInit(gnssDataRecvCallback, 1, 0);
	ret = hal_GnssInit(gnssDataRecvCallback, 3, 1);
	LOG_PRINTF("%s, ret: %d", __FUNCTION__, ret);

	ret = hal_GnssOpen();
	LOG_PRINTF("%s, ret: %d", __FUNCTION__, ret);	
	
	while (1)
	{
		memset(&gnssMsqData, 0x00, sizeof(gnssMsgParam));
		status = OSAMsgQRecv(gnss_msgq_ref, (UINT8 *)&gnssMsqData, sizeof(gnssMsgParam), OSA_SUSPEND);
		ASSERT(status == OS_SUCCESS);
		
		if (gnssMsqData.data){
						
			//gnss_process_nmea_sting(gnssMsqData.data);
			LOG_PRINTF("GNSS: %s", gnssMsqData.data);
			
			free(gnssMsqData.data);
			
			if (count++ > 100){				
				hal_GnssClose();
			}
		}
	}
}

int main(void)
{
    OSA_STATUS status;
	
	status = OSAMsgQCreate(&gnss_msgq_ref, "gnss_msgq_ref", sizeof(gnssMsgParam), 300, OS_FIFO);
    ASSERT(status == OS_SUCCESS);
	
	_task_stack = malloc(_STACK_SIZE);
	ASSERT(_task_stack != NULL);
	
    status = OSATaskCreate(&_task_ref, _task_stack, _STACK_SIZE, 100, "_task", _task, NULL);
    ASSERT(status == OS_SUCCESS);
	
	OSATaskSleep(15*200);
	hal_GnssCmd("$AIDINFO,*6E");
	return 0;
}